<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <script>
      // 将扁平数组处理成树形数组 -----------------------------------
      /**
       * 构造树型结构数据
       * @param {*} data 数据源
       * @param {*} id id字段 默认 'id'
       * @param {*} parentId 父节点字段 默认 'parentId'
       * @param {*} children 孩子节点字段 默认 'children'
       */
      function handleTree(data, id, parentId, children) {
        let config = {
          id: id || 'id',
          parentId: parentId || 'parentId',
          childrenList: children || 'children'
        }

        var childrenListMap = {}
        var nodeIds = {}
        var tree = []

        for (let d of data) {
          let parentId = d[config.parentId]
          if (childrenListMap[parentId] == null) {
            childrenListMap[parentId] = []
          }
          nodeIds[d[config.id]] = d
          childrenListMap[parentId].push(d)
        }

        for (let d of data) {
          let parentId = d[config.parentId]
          if (nodeIds[parentId] == null) {
            tree.push(d)
          }
        }

        for (let t of tree) {
          adaptToChildrenList(t)
        }

        function adaptToChildrenList(o) {
          if (childrenListMap[o[config.id]] !== null) {
            o[config.childrenList] = childrenListMap[o[config.id]]
          }
          if (o[config.childrenList]) {
            for (let c of o[config.childrenList]) {
              adaptToChildrenList(c)
            }
          }
        }
        return tree
      }

      // --------- 第二个扁平数组处理成树形数组 -----------------------------------
      function arrayToTree(arr) {
        const map = {}
        const tree = []

        // 将数组元素转换为以id为键的对象
        arr.forEach(item => {
          map[item.id] = item
        })

        // 遍历数组，将元素添加到对应的父元素的children数组中
        arr.forEach(item => {
          const parent = map[item.parentId]
          if (parent) {
            if (!parent.children) {
              parent.children = []
            }
            parent.children.push(item)
          } else {
            tree.push(item)
          }
        })

        return tree
      }
      // 示例使用：
      // const flatData = [
      //   { id: 1, name: '浙江省', level: 0, parentId: null },
      //   { id: 2, name: '杭州市', level: 1, parentId: 1 },
      //   { id: 3, name: '西湖区', level: 2, parentId: 2 },
      //   { id: 4, name: '宁波市', level: 1, parentId: 1 }
      // ]

      // function arrayToTree(arr, parentId = 0) {
      //   let tree = []
      //   let temp = []
      //   for (let i = 0; i < arr.length; i++) {
      //     if (arr[i].parentId === parentId) {
      //       let obj = arr[i]
      //       temp = arrayToTree(arr, obj.id)
      //       if (temp.length > 0) {
      //         obj.children = temp
      //       }
      //       tree.push(obj)
      //     }
      //   }
      //   return tree
      // }
      // let arrTree = arrayToTree(flatData, null)
      // console.log(arrTree)
      // 举例
      // const flatArr = [{
      //   id: 1,
      //   name: 'node1',
      //   parentId: null
      // },
      // {
      //   id: 2,
      //   name: 'node2',
      //   parentId: 1
      // },
      // {
      //   id: 3,
      //   name: 'node3',
      //   parentId: 1
      // },
      // {
      //   id: 4,
      //   name: 'node4',
      //   parentId: 2
      // },
      // {
      //   id: 5,
      //   name: 'node5',
      //   parentId: 2
      // },
      // {
      //   id: 6,
      //   name: 'node6',
      //   parentId: 3
      // },
      // ];
      // // 调用
      // const tree = flatToTree(flatArr, 'id', 'parentId', 'children');
      // console.log(tree);
      // 输出结果
      // [{
      //   "id": 1,
      //   "name": "node1",
      //   "parentId": null,
      //   "children": [{
      //     "id": 2,
      //     "name": "node2",
      //     "parentId": 1,
      //     "children": [{
      //       "id": 4,
      //       "name": "node4",
      //       "parentId": 2,
      //       "children": []
      //     },
      //     {
      //       "id": 5,
      //       "name": "node5",
      //       "parentId": 2,
      //       "children": []
      //     }
      //     ]
      //   },
      //   {
      //     "id": 3,
      //     "name": "node3",
      //     "parentId": 1,
      //     "children": [{
      //       "id": 6,
      //       "name": "node6",
      //       "parentId": 3,
      //       "children": []
      //     }]
      //   }
      //   ]
      // }]
      // 将扁平数组处理成树形数组 -----------------------------------
      // 示例使用：
      // const flatData = [
      //   { id: 1, name: '浙江省', level: 0, parentId: null },
      //   { id: 2, name: '杭州市', level: 1, parentId: 1 },
      //   { id: 3, name: '西湖区', level: 2, parentId: 2 },
      //   { id: 4, name: '宁波市', level: 1, parentId: 1 }
      // ]

      function arrayToTree(arr, parentId = 0) {
        let tree = []
        let temp = []
        for (let i = 0; i < arr.length; i++) {
          if (arr[i].parentId === parentId) {
            let obj = arr[i]
            temp = arrayToTree(arr, obj.id)
            if (temp.length > 0) {
              obj.children = temp
            }
            tree.push(obj)
          }
        }
        return tree
      }
      // let arrTree = arrayToTree(flatData, null)
      // console.log(arrTree)
      // 将树形数组处理成扁平数组 -----------------------------------
      function flattenTree(tree) {
        let flatArray = [] // 存放扁平结果的数组
        // 递归函数，用于遍历树结构
        function traverse(node) {
          flatArray.push(node) // 将当前节点添加到扁平数组中
          // 如果当前节点有子节点，遍历它们并递归调用traverse()函数
          if (node.children && node.children.length > 0) {
            for (let i = 0; i < node.children.length; i++) {
              traverse(node.children[i])
            }
          }
        }
        // 遍历整棵树
        for (let i = 0; i < tree.length; i++) {
          traverse(tree[i])
        }
        return flatArray
      }
      // 举例
      // const treeA = [{
      //   id: 1,
      //   children: [{
      //     id: 2
      //   },
      //   {
      //     id: 3,
      //     children: [{
      //       id: 4
      //     },
      //     {
      //       id: 5
      //     }
      //     ]
      //   },
      //   {
      //     id: 6
      //   }
      //   ]
      // },
      // {
      //   id: 7,
      //   children: [{
      //     id: 8
      //   },
      //   {
      //     id: 9
      //   }
      //   ]
      // }
      // ];
      // // 调用
      // const flatArray = flattenTree(treeA);
      // console.log(flatArray);
      // 输出:
      // [
      //   { id: 1, children: [Object] },
      //   { id: 2 },
      //   { id: 3, children: [Object] },
      //   { id: 4 },
      //   { id: 5 },
      //   { id: 6 },
      //   { id: 7, children: [Object] },
      //   { id: 8 },
      //   { id: 9 }
      // ]
    </script>
  </body>
</html>
